refactor(db): drop six verified-dead repository/bundle methods (vulture, #1136) - #1287
Conversation
ad6f390 to
67eb68a
Compare
…re, #1136) Removes six methods flagged by vulture and verified dead across all five surfaces (FastAPI/Web/CLI/agent/TUI). For each, repo-wide grep (src/ tests/ scripts/ docs/ conftest.py) returned exactly 1 hit — the definition — with no string references. Dynamic repo access in the codebase targets other specific names (clear_dialogs, get_recent_for_channels, get_channels, …); the dispatcher's dynamic dispatch is f"_handle_{command}"-shaped and unrelated. Repository methods (underlying repo layer stays — these are unused readers): 1. ChannelsRepository.get_channels_by_tag — born in #271 (tags feature) with no caller (git grep at 2af529e: definition only). The tag feature uses list_all_tags/create_tag/delete_tag/set_channel_tags/get_channel_tags (see src/cli/commands/channel.py); this reverse reader was never wired to any surface. 2. DialogCacheRepository.has_dialogs — born in bc2bddd with no caller. All live dialog_cache methods (enumerated from call sites): clear_all_dialogs, clear_dialogs, count_dialogs, get_all_phones, get_cached_at, get_dialog, list_dialogs, replace_dialogs — has_dialogs absent. 3. GenerationRunsRepository.list_by_status — definition-only at every commit that touched it (#292, #555, #780); moderation/runs surfaces use list_pending_moderation / list_runs instead. Bundle wrappers (unused thin wrappers over LIVE repo methods that stay): 4. AccountBundle.list_live_usable_accounts — AccountsRepository. get_live_usable_accounts stays (17 live refs). 5. AccountBundle.update_premium — AccountsRepository.update_account_premium stays (24 live refs). 6. MessageBundle.get_message_stats — MessagesRepository.get_stats stays (used via Database.get_stats -> dashboard route). No public-API/parity impact: none of the six is reachable from any of the five surfaces. Part of #1136 / #1130. Co-Authored-By: Claude <noreply@anthropic.com>
67eb68a to
cc101ad
Compare
🔍 Local review (cycle 1)Reviewed locally ( Both reviewers: clean — 0 findings, Codex verdict Step 1.5 (dead-code re-verification on fresh main) — all 6 deleted methods show 0 references:
Underlying repo methods stay live: One self-found cosmetic issue fixed in this commit (cc101ad): removing Codex exhaustive search confirmed: base had only the 6 definitions, diff deletes only those, 0 remaining refs across No |
bundles.py duplicated identical repository pass-through methods across bundles (ChannelBundle/CollectionBundle channel+task ops, get_setting/ set_setting in four bundles, account reads in three, message search/batch insert in two, scheduler task reads). jscpd flagged the top clone cluster of issue #1135. Consolidate each duplicated wrapper group into a repo-scoped plain-class mixin (_ChannelOps, _CollectionTaskCreateOps, _CollectionTaskReadOps, _SettingsOps, _NotificationQueriesOps, _MessageOps, _AccountReadOps, _SearchLogReadOps). Mixins are deliberately NOT dataclasses: their attribute annotations do not become dataclass fields, so every bundle's positional constructor order is unchanged. Rebased onto a main where #1287 (vulture #1136) already dropped three dead bundle methods (list_live_usable_accounts, update_premium, get_message_stats) — those were unique to their bundles, so the dedup groups are unaffected; the rebase just no longer carries them. The set_active name collision is handled by resolution: ChannelBundle/ CollectionBundle get _ChannelOps.set_active(pk), while AccountBundle (account_id), SearchQueryBundle (sq_id), PipelineBundle (pipeline_id) keep their own class-body definitions. Public API verified equivalent by inspect.signature over MRO: identical method set per bundle, identical fields, set_active resolves to the correct definition per bundle. Bundle method count 135 -> 108; the test_db_access_conventions ratchet baseline is lowered accordingly. Part of #1135 (axis 5 of #1130). Co-Authored-By: Claude <noreply@anthropic.com>
…#1283) bundles.py duplicated identical repository pass-through methods across bundles (ChannelBundle/CollectionBundle channel+task ops, get_setting/ set_setting in four bundles, account reads in three, message search/batch insert in two, scheduler task reads). jscpd flagged the top clone cluster of issue #1135. Consolidate each duplicated wrapper group into a repo-scoped plain-class mixin (_ChannelOps, _CollectionTaskCreateOps, _CollectionTaskReadOps, _SettingsOps, _NotificationQueriesOps, _MessageOps, _AccountReadOps, _SearchLogReadOps). Mixins are deliberately NOT dataclasses: their attribute annotations do not become dataclass fields, so every bundle's positional constructor order is unchanged. Rebased onto a main where #1287 (vulture #1136) already dropped three dead bundle methods (list_live_usable_accounts, update_premium, get_message_stats) — those were unique to their bundles, so the dedup groups are unaffected; the rebase just no longer carries them. The set_active name collision is handled by resolution: ChannelBundle/ CollectionBundle get _ChannelOps.set_active(pk), while AccountBundle (account_id), SearchQueryBundle (sq_id), PipelineBundle (pipeline_id) keep their own class-body definitions. Public API verified equivalent by inspect.signature over MRO: identical method set per bundle, identical fields, set_active resolves to the correct definition per bundle. Bundle method count 135 -> 108; the test_db_access_conventions ratchet baseline is lowered accordingly. Part of #1135 (axis 5 of #1130). Co-authored-by: axisrow <axisrow@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
Part of #1136 (vulture axis of epic #1130). Six methods deleted; each verified dead across all five surfaces (FastAPI/Web/CLI/agent/TUI) before removal. Per #1136, "dead by graph" ≠ "unneeded" — so every candidate passed a full grep + git-history check first.
For each: repo-wide grep (
src/ tests/ scripts/ docs/ conftest.py) returned exactly 1 hit — the definition — with no string references. The codebase's dynamic repo access targets other specific names (clear_dialogs,get_recent_for_channels,get_channels, …), and the dispatcher's dynamic dispatch isf"_handle_{command}"-shaped and unrelated to any of these.Repository methods (unused readers; the repo layer stays)
ChannelsRepository.get_channels_by_tag— born in feat: RSS, tags, S3 storage, refinement pipeline, ReAct fallback, test fixes #271 (tags feature) with no caller (git grepat 2af529e: definition only). The tag feature's surfaces uselist_all_tags/create_tag/delete_tag/set_channel_tags/get_channel_tags(seesrc/cli/commands/channel.py); this reverse reader ("channels by tag") was never wired to any surface.DialogCacheRepository.has_dialogs— born in bc2bddd (persist dialog cache) with no caller. Live dialog_cache methods (enumerated from call sites):clear_all_dialogs,clear_dialogs,count_dialogs,get_all_phones,get_cached_at,get_dialog,list_dialogs,replace_dialogs—has_dialogsabsent.GenerationRunsRepository.list_by_status— definition-only at every commit that touched it (feat: add 12 missing agent tools and fix ghost MODULE_GROUPS entries #292, [codex] close issue 554 audit gaps #555, feat(parity): close CLI ↔ Web ↔ Agent-tool parity gaps #780); moderation/runs surfaces uselist_pending_moderation/list_runsinstead.Bundle wrappers (unused thin wrappers over LIVE repo methods that stay)
AccountBundle.list_live_usable_accounts—AccountsRepository.get_live_usable_accountsstays (17 live refs).AccountBundle.update_premium—AccountsRepository.update_account_premiumstays (24 live refs).MessageBundle.get_message_stats—MessagesRepository.get_statsstays (used viaDatabase.get_stats→ dashboard route).No public-API/parity impact: none of the six is reachable from any of the five surfaces.
Verification (no regression guard possible — code is gone; proof = green suite + this note)
ruff check src/ tests/ conftest.py— clean.pytest tests/repositories/ tests/test_bundles.py— 426 passed.pytest tests/ -m "not aiosqlite_serial" -n autothen-m aiosqlite_serial) — green. The only failures elsewhere are pre-existing onorigin/main:tests/test_quality_scoring_service.py(7 tests fail on clean main) and the xdist-flakytests/routes/test_debug_routes.py::test_debug_timing_page; both deselected and reproduced on clean main, unrelated to this diff.Not deleted here (doubtful → left for owner decision)
update_flood,save_stats,list_notification_queriesare called only by their own unit tests and are deliberately left untouched pending owner call (test-locking vs delete-with-tests). They are flagged in the issue audit, not here.Part of #1136 / #1130.